package com.liqi.frame.comm.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.liqi.frame.comm.Constants;
import com.liqi.frame.comm.dto.MenuDto;
import com.liqi.frame.comm.service.MenuService;
import com.liqi.frame.comm.token.TokenUtil;
import com.liqi.frame.comm.util.AjaxUtil;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 权限校验 Filter
 */
public class PermissionFilter extends AccessControlFilter {
	private static final Log log = LogFactory.get();

	@Autowired
	MenuService menuService;

	@Override
	protected boolean isAccessAllowed(ServletRequest request,
                                      ServletResponse response, Object mappedValue) throws Exception {

		if (AjaxUtil.isAjax(request)) {
			return Boolean.TRUE;
		}
		
		//先判断带参数的权限判断
		Subject subject = getSubject(request, response);
		// 判断是不是管理员账号
		if (TokenUtil.isAdministrator()) {
			return Boolean.TRUE;
		}
		if(null != mappedValue){
			String[] arra = (String[])mappedValue;
			for (String permission : arra) {
				if(subject.isPermitted(permission)){
					return Boolean.TRUE;
				}
			}
		}
		HttpServletRequest httpRequest = ((HttpServletRequest)request);
		/**
		 * 此处是改版后，为了兼容项目不需要部署到root下，也可以正常运行，但是权限没设置目前必须到root 的URI，
		 * 原因：如果你把这个项目叫 ShiroDemo，那么路径就是 /ShiroDemo/xxxx.shtml ，那另外一个人使用，又叫Shiro_Demo,那么就要这么控制/Shiro_Demo/xxxx.shtml 
		 * 理解了吗？
		 * 所以这里替换了一下，使用根目录开始的URI
		 */
		
		String uri = httpRequest.getRequestURI();//获取URI
		String basePath = httpRequest.getContextPath();//获取basePath
		if(null != uri && uri.startsWith(basePath)){
			uri = uri.replaceFirst(basePath, "");
		}

		List<MenuDto> menuList =  menuService.getMenuList();
		String menuPermission = null;
		for (int i = 0; i < menuList.size(); i++) {
			String menuHref = menuList.get(i).getHref();
			if (menuHref!=null && !"".equals(menuHref) && StrUtil.removePrefix(menuHref,"/").equalsIgnoreCase(StrUtil.removePrefix(uri,"/"))) {
				menuPermission = menuList.get(i).getMenuKey();
			}
		}
		if(menuPermission!=null && subject.isPermitted(menuPermission)){
			return Boolean.TRUE;
		}
//		if(AjaxUtil.isAjax(request)){
//			Map<String,String> resultMap = new HashMap<String, String>();
//			log.debug("当前用户没有登录，并且是Ajax请求！");
//			resultMap.put("httpStatus", "403");
//			resultMap.put("message", "当前用户没有权限。");//当前用户没有登录！
//			AjaxUtil.out(response, resultMap);
//		}
		return Boolean.FALSE;
	}


	@Override
	protected boolean onAccessDenied(ServletRequest request,
                                     ServletResponse response) throws Exception {

		if(!AjaxUtil.isAjax(request)) {
			Subject subject = getSubject(request, response);
			if (null == subject.getPrincipal()) {//表示没有权限，重定向到没有权限提示页面
				saveRequest(request);
				WebUtils.issueRedirect(request, response, Constants.LOGIN_URL);
			} else {
				if (StringUtils.hasText(Constants.UNAUTHORIZED)) {//如果有未授权页面跳转过去
					WebUtils.issueRedirect(request, response, Constants.UNAUTHORIZED);
				} else {//否则返回401未授权状态码
					WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
				}
			}
		}
		return Boolean.FALSE;
	}

}
